#include <stdio.h>
#include <vector>
#include <map>
#include <climits>
struct Point {
    int x;
    int y;
    Point() : x(0), y(0) {}
    Point(int a, int b) : x(a), y(b) {}
};
/*
how to present a line? k and one points
Situation: for one point:
           other points exists the following situation
                A. same points duplicate, every line need add the duplicate num
                B1. k exists
                B2. k not exists
*/
int maxPoints(std::vector<Point> &points) {
    if (points.size() <= 2)
    {
        return points.size();
    }        

    std::map<double, int> lines;
    std::map<double, int>::iterator it;
    double k = 0; //for slope
    int i = 0; //for loop
    int j = 0; // for loop
    int max_points = 0;
    int size = points.size();
    int x0 = 0;
    int y0 = 0;
    int x1 = 0;
    int y1 = 0;
    int duplicate = 0;
    
    for (i = 0; i < size; ++i)
    {
        x0 = points[i].x;
        y0 = points[i].y;
        //set variable default
        lines.clear();
        duplicate = 1;
        for (j = i - 1; j >= 0; --j)
        {
            x1 = points[j].x;
            y1 = points[j].y;
            // duplicate 
            if (x1 == x0 && y1 == y0)
            {
                duplicate++;
            }
            else
            {
                // test whether the k exists or not 
                k = x1 == x0 ? INT_MAX: (1.0*(y1 - y0))/(x1 - x0);
                // line[k] set default 0
                lines[k]++;
            }
        }
        // aimed at reduce the computation in compare procedure
        max_points -= duplicate;
        for (it = lines.begin(); it != lines.end(); ++it)
        {
            max_points = max_points >= (it->second) ? max_points:(it->second);
        }
        max_points += duplicate; 

        //if the lines is empty
        if (lines.empty())
        {
            max_points = duplicate;
        }
    }
    return max_points;
}

int main(int argc, char const *argv[])
{
    std::vector<Point> points;
    points.insert(points.begin(),Point(1, 1));
    points.insert(points.begin(),Point(1, 1));
    points.insert(points.begin(),Point(2, 1));
    printf("%d\n", maxPoints(points));
    return 0;
}

/*
duplicate = 1;

        for (j = 0; j < size; ++j)
        {
            x1 = points[j].x;
            y1 = points[j].y;
            // duplicate 
            if (x1 == x0 && y1 == y0)
            {
                duplicate++;
            }
            else
            {
                // test whether the k exists or not 
                k = x1 == x0 ? INT_MAX: (1.0*(y1 - y0))/(x1 - x0);
                // line[k] set default 0
                lines[k]++;
            }
        }*/